<%@ page pageEncoding="UTF-8"%>
<%!
	// 随访节点状态
	public static final Integer NO_PUSH = 0;     // 未推送
	public static final Integer HAS_PUSH = 1;    // 已推送未确认
	public static final Integer CONFIRMED = 2;   // 已确认
	// 随访类型定义
	public static final Integer SURVEY_CATEGORY = 3;   // 天下专家随访大类
	public static final Integer SURVEY_QUESTION_CATEGORY = 30;   // 天下专家随访节点小类
	// 随访推送范围定义
	public static final Integer SURVEY_PUSH_NO = 0;   // 不推送
	public static final Integer SURVEY_PUSH_PATIENT = 1;   // 只推送患者
	public static final Integer SURVEY_PUSH_DOCTOR = 2;   // 只推送医生
	public static final Integer SURVEY_PUSH_ALL = 3;   	// 医生、患者都推送
	public static final String SURVEY_PUSH_TIME = " 08:00:00";
	// 对于加入到visit中的随访，应设置每天定时推送任务，遍历visit数据表，根据isConfirmed状态判断为NO_PUSH且推送时间为当天，则推送后标记isConfirmed为HAS_PUSH
	// 随访节点状态 state 0未开始 1可编辑 2已完成 3已过期未确认
	public static final Integer POINT_NO_START = 0;  
	public static final Integer POINTING = 1;  
	public static final Integer POINT_COMPLETE = 2;   
	public static final Integer POINT_EXPIRE = 3;   
	// 附件类型
	public static final String LINK_SURVEY_TYPE = "0";   
	public static final String LINK_NEWS_TYPE = "1";   
	// 附件类型前缀
	public static final String LINK_SURVEY_SUFFIX = LINK_SURVEY_TYPE + "_";   
	public static final String LINK_NEWS_SUFFIX = LINK_NEWS_TYPE + "_";  
	// 节点是否默认显示
	public static final Integer isDefaultDisplay = 1;   
	public static final Integer noDefaultDisplay = 0;  
	// 问卷题型
	static final Integer SURVEY_QUESTION_TYPE_SINGLE_V2 = 0; // 单选题
	static final Integer SURVEY_QUESTION_TYPE_MULTI_V2 = 1; // 多选题
	static final Integer SURVEY_QUESTION_TYPE_SINGLE_NOMUST_V2 = 2; // 非必填项的单选题
	static final Integer SURVEY_QUESTION_TYPE_INPUT_V2 = 3; // 填空题
	static final Integer SURVEY_QUESTION_TYPE_GRADE_V2 = 4; // 评分题 拖拽
	public List<Map> queryVisit(Integer uid, Integer hospital, Integer deptId, Integer doctorUid) {
		Message msg = new Message(0, "查询成功");
		String tabels = "Visit v, Survey as s";
		Where where = new Where("v.hospital=", hospital).and("v.patientUid=", uid).and("v.category=", SURVEY_CATEGORY).and("v.status=", STATUS_ENABLE).and("v.surveyId=s.id").and("s.status=", STATUS_ENABLE);
		if (deptId != -1) {
			if (hospital == 999) {
				List<Hospital> hospitals = QBuilder.db("basedb").queryHql("from Hospital where id=" + deptId);
				if (!isEmpty(hospitals))
					deptId = hospitals.get(0).getHospital();
			}
			tabels = "Visit v, Survey as s, User as u";
			where.and("u.id=v.doctorUid").and("u.deptId=", deptId);
		}
		if (doctorUid != -1) {
			where.and("v.doctorUid=", doctorUid);
		}
		List<Map> parentVisitList = QBuilder.db("basedb").select("new map(v.doctorUid as doctor_uid, v.patientUid as patient_uid, v.sendTime as send_time, v.surveyId as survey_id, s.title as title)").from(tabels).where(where).order("v.cTime", "desc").query().getResultObj();
		List<Map> visitList = QBuilder.db("basedb").select("new map(id as point_id, sendTime as send_time, surveyId as survey_id, isconfirmed as isconfirmed, reconfirmedTime as reconfirmed_time)").from("Visit v").where(new Where("v.hospital=", hospital).and("v.patientUid=", uid).and("v.category=", SURVEY_QUESTION_CATEGORY).and("v.status=", STATUS_ENABLE)).order("id", "asc").query().getResultObj();
		String surveryIds = "-1";
		List<Integer> uids = new ArrayList<Integer>();
		for (Map parent:parentVisitList) {
			surveryIds = surveryIds + "," + Tools.getDesc(parent.get("survey_id"));
			uids.add((Integer)parent.get("doctor_uid"));
			uids.add((Integer)parent.get("patient_uid"));
		}
		Map<Integer, User> userMap =  usersByUids(uids);
		List<SurveyQuestion> surveyQuestionList = QBuilder.db("basedb").select().from("SurveyQuestion sq").where(new Where("sq.hospital=", hospital).and("sq.type=", 0).and("sq.status=", STATUS_ENABLE).and("sq.surveyId in(" + surveryIds + ")")).query().getResultObj();
		Map<Integer, SurveyQuestion> sqMap = new HashMap<Integer, SurveyQuestion>();
		Map<Integer, Integer> surveyQuestionMap = new HashMap<Integer, Integer> ();
		Map<String, Map> linkSource = new HashMap<String, Map> ();
		String newsIds = "-1";
		String questIds = "-1";
		for (SurveyQuestion surveyQuestion:surveyQuestionList) {
			sqMap.put(surveyQuestion.getId(), surveyQuestion);
			surveyQuestionMap.put(surveyQuestion.getId(), surveyQuestion.getSurveyId());
			List<Map> sourceList = JSONUtil.fromJson(surveyQuestion.getDetail(), new TypeReference<List<Map>>(){});
			for (Map source:sourceList) {
				String type = Tools.getDesc(source.get("link_type")).replace(".0", "");
				String linkId = Tools.getDesc(source.get("link_id")).replace(".0", "");
				if (type.equals(LINK_SURVEY_TYPE))
					questIds = questIds + "," + source.get("link_id");
				else 
					newsIds = newsIds + "," + source.get("link_id");
			}
		}
		List<Map> quests = QBuilder.db("basedb").select("new map(id as id, title as title)").from("Survey s").where(new Where("s.status=", STATUS_ENABLE).and("s.id in(" + questIds + ")")).query().getResultObj();
		for (Map map:quests) {
			linkSource.put(LINK_SURVEY_SUFFIX + map.get("id"),  map);
		}
		List<Map> news = QBuilder.db("basedb").select("new map(id as id, newsId as news_id, title as title)").from("News n").where(new Where("n.status=", STATUS_ENABLE).and("n.id in(" + newsIds + ")")).query().getResultObj();
		for (Map map:news) {
			linkSource.put(LINK_NEWS_SUFFIX + map.get("id"),  map);
		}
		List<String> newsOperateList = QBuilder.db("basedb").select("distinct oid").from("OperateHistory as o").where(new Where("o.status=", STATUS_ENABLE).and("o.uid=", uid).and("o.hospital=", hospital).and("o.operate=", SEE).and("o.category=", NEWS_CATEGORY)).query().getResultObj();
		List<String> answerList = QBuilder.db("basedb").select("concat(sa.visitId , '_', sa.surveyId)").from("SurveyAnswer as sa").where(new Where("sa.status=", STATUS_ENABLE).and("sa.hospital=", hospital).and("uid=", uid)).query().getResultObj();
		Date dateNow = new Date();
		String dateNowStr = DateUtil.formatDate(dateNow);
		// state 0未开始 1可编辑 2已完成 3已过期未确认
		for (Map parent:parentVisitList) {
			Integer id = (Integer)parent.get("id");
			Integer surveyId = (Integer)parent.get("survey_id");
			List<Map> subList = new ArrayList<Map>();
			for (int i = 0;i < visitList.size(); i++) {
				Map map = visitList.get(i);
				Integer state = POINT_NO_START;
				Date sendDate = DateUtil.parseDateTime(Tools.getDesc(map.get("send_time")).replace("08:00:00", "23:59:59"));
				String sendDateStr = DateUtil.formatDate(sendDate);
				Integer subSurveyId = (Integer)map.get("survey_id");
				Integer parentSurveyId = surveyQuestionMap.get(subSurveyId);
				if (surveyId.equals(parentSurveyId)) {
					Integer isconfirmed = (Integer)map.remove("isconfirmed");
					if (dateNow.after(sendDate) && isconfirmed == 2) 
						state = POINT_COMPLETE;
					else if (dateNowStr.equals(sendDateStr)) 
						state = POINTING;
					else if (dateNow.before(sendDate)) 
						state = POINT_NO_START;
					else 
						state = POINT_EXPIRE;
					map.put("state", state);
					SurveyQuestion surveyQuestion = sqMap.get(subSurveyId);
					map.put("title", surveyQuestion.getTitle());
					map.put("show_order", subList.size() + 1);
					List<Map> sourceList = JSONUtil.fromJson(surveyQuestion.getDetail(), new TypeReference<List<Map>>(){});
					Integer newsCount = 0;
					Integer newsCompleteCount = 0;
					Integer surveyCount = 0;
					Integer surveyCompleteCount = 0;
					Integer pointId = (Integer)map.get("point_id");
					for (Map source:sourceList) {
						source.put("completed", 0);
						String type = Tools.getDesc(source.get("link_type")).replace(".0", "");
						String linkId = Tools.getDesc(source.get("link_id")).replace(".0", "");
						if (type.equals(LINK_SURVEY_TYPE)) {
							surveyCount++;
							if (answerList.contains(pointId + "_" + linkId)) {
								source.put("completed", 1);
								surveyCompleteCount++;
							}
						} else {
							newsCount++;
							if (newsOperateList.contains(linkId)) {
								newsCompleteCount++;
								source.put("completed", 1);
							}
						}
						if (linkSource.get(type + "_" + linkId) != null)
							source.putAll(linkSource.get(type + "_" + linkId));
						if (type.equals(LINK_SURVEY_TYPE)) 
							source.put("id", Tools.getInt(source.get("id") + ""));
						else 
							source.put("id", Tools.getInt(source.get("news_id") + ""));
						source.remove("news_id");
						source.remove("link_id");
						source.remove("link_type");
						source.remove("point_id");
						source.put("type", Tools.getInt(type));
					}
					map.put("attachment", sourceList);
					map.put("news_count", newsCount);
					map.put("news_complete", newsCompleteCount);
					map.put("survey_count", surveyCount);
					map.put("survey_complete", surveyCompleteCount);
					map.put("default_show", noDefaultDisplay);
					subList.add(map);
				}
			}
			parent.put("points", subList);
			User doctor = userMap.get((Integer)parent.get("doctor_uid")) == null?new User():userMap.get((Integer)parent.get("doctor_uid"));
			User patient = userMap.get((Integer)parent.get("patient_uid")) == null?new User():userMap.get((Integer)parent.get("patient_uid"));
			parent.put("doctor_name", Tools.getDesc(doctor.getName()));
			parent.put("doctor_avatar", getDefaultAvatar(doctor));
			parent.put("patient_name", !isEmpty(patient.getName())?patient.getName():!isEmpty(patient.getNickName())?patient.getNickName():patient.getUserName());
			parent.put("patient_avatar", getDefaultAvatar(patient));
			Integer subSize = subList.size();
			boolean iSetDefault = false;
			for (Map sub:subList) {
				sub.put("point_count", subSize);
				Integer state = (Integer)sub.get("state");
				if (state.equals(POINTING)) {
					iSetDefault = true;
					sub.put("default_show", isDefaultDisplay);
					break;
				}
			}
			if (subSize != 0 && !iSetDefault) {
				Map firstVisit = subList.get(0);
				Map finalVisit = subList.get(subList.size() - 1);
				Integer finalVisitState = (Integer)finalVisit.get("state");
				// 如果最后节点不是未开始状态，则默认显示
				if (!finalVisitState.equals(POINT_NO_START)) {
					finalVisit.put("default_show", isDefaultDisplay);
				} else {
					Integer state = (Integer)firstVisit.get("state");
					if (state.equals(POINT_NO_START)) 
						firstVisit.put("default_show", isDefaultDisplay);
					else if (state.equals(POINT_COMPLETE)) 
						findCompletePoint(subList, 0);
					else 
						subList.get(subSize - 1).put("default_show", isDefaultDisplay);
				}
			}
			List recodeList = QBuilder.db("basedb").select("count(*)").from("time_line").where(new Where("patient_uid=", uid).and("oid=", parent.get("survey_id")).and("status=", STATUS_ENABLE)).query().getResultObj();
			parent.put("record_count", recodeList.get(0));
		}
		return parentVisitList;
	}
	
	// 处理默认显示的节点
	public void findCompletePoint(List<Map> list, int index) {
		if (index <= (list.size() -1)) {
			Map map = list.get(index);
			Integer state = (Integer)map.get("state");
			if (state.equals(POINT_COMPLETE) || state.equals(POINT_EXPIRE)) 
				findCompletePoint(list, ++index);
			else 
				map.put("default_show", isDefaultDisplay);
		}
	}
	
	// 为Map<Integer, List<Map>>某个键的值list增加一个元素
	void addListKeyValue(Map<Integer, List<Map>> parent, Integer key, Map map) {
		List<Map> list = isEmpty(parent.get(key))?new ArrayList<Map>():parent.get(key);
		list.add(map);
		parent.put(key, list);
	}
	
	// 随访量表完善信息
	List<Map> completeSurveyInfo(Map<Integer, List<Map>> parent, Map<Integer, String> visitTitleMap, Map<Integer, User> userMap,Map<Integer, Integer> surveyPatientMap, Map<Integer, String> surveyTitleMap) {
		List<Map> list = new ArrayList<Map>();
		Set<Integer> keySet = parent.keySet();
		for (Integer key:keySet) {
			Map map = new HashMap();
			User user = userMap.get(surveyPatientMap.get(key));
			map.put("patient_name", !isEmpty(user.getName())?user.getName():!isEmpty(user.getNickName())?user.getNickName():user.getUserName());
			map.put("avatar", getDefaultAvatar(user));
			map.put("gender", Tools.getInt(user.getGender()+"", 1));
			List<Map> surveys = parent.get(key)==null?new ArrayList<Map>():parent.get(key);
			for (Map survey:surveys) {
				survey.put("point_name", visitTitleMap.get((Integer)survey.get("point_id")));
				survey.put("survey_title", surveyTitleMap.get((Integer)survey.get("survey_id")));
			}
			map.put("visit_title", visitTitleMap.get(key));
			map.put("surveys", surveys);
			map.put("survey_count", surveys.size());
			list.add(map);
		}
		return list;
	}
	
	// 把查询出来的随访量表归类
	public List<Map> querySurveys(Integer uid, Integer hospital, String range) {
		User user = userByUid(uid);
		Integer deptId = user.getDeptId()==null?-1:user.getDeptId();
		List<Map> visits = QBuilder.db("basedb").select("new map(v.id as visit_id, sq.surveyId as parent_survey_id ,v.isconfirmed as isconfirmed, v.sendTime as send_time, sq.detail as detail,sq.id as id,sq.title as title, v.reconfirmedTime as reconfirmed_time)").from("Visit as v,SurveyQuestion as sq").where(new Where("v.doctorUid=", uid).and("v.status=", STATUS_ENABLE).and("sq.status=", STATUS_ENABLE).and("v.category=", SURVEY_QUESTION_CATEGORY).and("sq.id=v.surveyId")).query().getResultObj();
		List<Map> answerList = QBuilder.db("basedb").select("new map(sa.visitId as visit_id, sa.surveyId as survey_id)").from("SurveyAnswer as sa").where(new Where("sa.status=", STATUS_ENABLE).and("sa.hospital=", hospital)).query().getResultObj();
		List<String> answers = new ArrayList<String>();
		for (Map answer:answerList) {
			answers.add(Tools.getDesc(answer.get("visit_id")) + "_" + Tools.getDesc(answer.get("survey_id")));
		}
		List<Map> parentSurveys = QBuilder.db("basedb").select("new map(s.title as title, s.id as id, v.id as parent_visit_id,v.patientUid as patient_uid)").from("Visit as v,Survey as s").where(new Where("v.doctorUid=", uid).and("v.status=", STATUS_ENABLE).and("s.status=", STATUS_ENABLE).and("v.category=", SURVEY_CATEGORY).and("s.id=v.surveyId").and("v.doctorUid=", uid)).query().getResultObj();
		Map<Integer, Integer> surveyMap = new HashMap<Integer, Integer> ();
		Map<Integer, String> visitTitleMap = new HashMap<Integer, String> ();
		Map<Integer, Integer> surveyPatientMap = new HashMap<Integer, Integer>();
		List<Integer> uids = new ArrayList<Integer>();
		for (Map map:parentSurveys) {
			surveyMap.put((Integer)map.get("id"), (Integer)map.get("parent_visit_id"));
			visitTitleMap.put((Integer)map.get("parent_visit_id"), Tools.getDesc(map.get("title")));
			surveyPatientMap.put((Integer)map.get("parent_visit_id"), (Integer)map.get("patient_uid"));
			uids.add((Integer)map.get("patient_uid"));
		}
		Map<Integer, User> userMap = usersByUids(uids);
		Date dateNow = new Date();
		Map<Integer, List<Map>> parentNoCompleteVisitMap = new HashMap<Integer, List<Map>>();
		Map<Integer, List<Map>> parentCompletedVisitMap = new HashMap<Integer, List<Map>>();
		Map<Integer, List<Map>> parentExpiredVisitMap = new HashMap<Integer, List<Map>>();
		String surveyLinkIds = "-1";
		for (Map map:visits) {
			Integer visitId = (Integer)map.get("visit_id");
			visitTitleMap.put(visitId, Tools.getDesc(map.get("title")));
			Integer parentVisitId = surveyMap.get((Integer)map.get("parent_survey_id"));
			Integer state = POINT_NO_START;
			Date sendDate = DateUtil.parseDateTime(Tools.getDesc(map.get("send_time")).replace("08:00:00", "23:59:59"));
			String sendDateTime = Tools.getDesc(map.get("send_time"));
			String confirmDateTime = Tools.getDesc(map.get("reconfirmed_time"));
			// 略过的节点不算待完成
			if (sendDateTime.equals(confirmDateTime)) {
				state = POINT_COMPLETE;
			}
			Integer isconfirmed = (Integer)map.remove("isconfirmed");
			if (dateNow.after(sendDate) && isconfirmed != 2) 
				state = POINT_EXPIRE;
			List<Map> sourceList = JSONUtil.fromJson(Tools.getDesc(map.get("detail")), new TypeReference<List<Map>>(){});
			for (Map source:sourceList) {
				String type = Tools.getDesc(source.get("link_type")).replace(".0", "");
				String linkId = Tools.getDesc(source.get("link_id")).replace(".0", "");
				if (type.equals(LINK_SURVEY_TYPE)) {
					String str = visitId + "_" + linkId;
					surveyLinkIds = surveyLinkIds + "," + linkId;
					Map totalMap = new HashMap();
					totalMap.put("point_id", visitId);
					totalMap.put("survey_id", Tools.getInt(linkId));
					if (state.equals(POINT_COMPLETE)) 
						continue;
					if (state.equals(POINT_EXPIRE)) 
						addListKeyValue(parentExpiredVisitMap, parentVisitId, totalMap);
					else if (answers.contains(str)) 
						addListKeyValue(parentCompletedVisitMap, parentVisitId, totalMap);
					else  
						addListKeyValue(parentNoCompleteVisitMap, parentVisitId, totalMap);
				}
			}
		}
		Map<Integer, String> surveyTitleMap = new HashMap<Integer, String>();
		List<Map> surveyTitles = QBuilder.db("basedb").select("new map(s.title as title, s.id as id)").from("Survey as s").where(new Where("s.id in(" + surveyLinkIds + ")")).query().getResultObj();
		for (Map map:surveyTitles) {
			surveyTitleMap.put((Integer)map.get("id"), Tools.getDesc(map.get("title")));
		}
		Map resultTable = new HashMap();
		if ("to_complete".equals(range))
			return completeSurveyInfo(parentNoCompleteVisitMap, visitTitleMap, userMap, surveyPatientMap, surveyTitleMap);
		else if ("completed".equals(range)) 
			return completeSurveyInfo(parentCompletedVisitMap, visitTitleMap, userMap, surveyPatientMap, surveyTitleMap);
		else if ("expired".equals(range)) 
			return completeSurveyInfo(parentExpiredVisitMap, visitTitleMap, userMap, surveyPatientMap, surveyTitleMap);
		else 
			return new ArrayList<Map>();
	}
%>
